<?php
/**
 * The login (auth) controller class. Handles login and logout requests,
 * as well as reset password functionality and registering new users.
 * 
 * @package disputeo
 * @version 1.0
 * @author jimmy.dixon
 */

class LoginController extends Zend_Controller_Action
{
    /**
     * @var Application_Model_UserMapper
     */
    protected $_userMapper;
    
    /**
     * Initialise forms and mapper
     */
    public function init()
    {
        $this->_userMapper = new Application_Model_UserMapper();
        $this->_helper->formCheck->register(new Application_Form_Login())
            ->register(new Application_Form_Register())
            ->register(new Application_Form_Reset())
            ->register(new Application_Form_Password())
            ->errorMessages();
    }

    /**
     * index action
     */
    public function indexAction()
    {
        $this->view->loginForm = $this->forms['login'];
        $this->view->registerForm = $this->forms['register'];
        if (isset($this->_messenger->userNotFound)) {
            $this->view->loginForm->addNotFoundError();
        }
    }

    /**
     * login action
     */
    public function loginAction()
    {
        if ($this->_helper->formCheck('login')) {
            $user = new Application_Model_User();
            $user->setUsername($this->forms['login']->getValue('username'))
                ->setPassword($this->forms['login']->getValue('password'));
            if ($this->_authenticate($user)) {
                $this->_session->persist($this->forms['login']->getValue('remember'));
                $this->_redirect('/index');
            } else {
                $this->_messenger->addMessage('userNotFound');
            }
        }
        $this->_redirect('/login/index');
    }

    /**
     * logout action
     */
    public function logoutAction()
    {
        Zend_Auth::getInstance()->clearIdentity();
        $this->_session->clear();
        $this->_redirect('/index');
    }

    /**
     * register action
     */
    public function registerAction()
    {
        if ($this->_helper->formCheck('register')) {
            $data = $this->forms['register']->getValues();
            $user = $this->_userMapper->create($data);
            $this->_mailer->sendWelcomeEmail($user);
            $this->_messenger->addMessage('newuser');
            $this->_authenticate($user);
            $this->_redirect('/index');
        }
        $this->_redirect('/login/index#register');
    }

    /**
     * reset action
     */
    public function resetAction()
    {
        if ($this->_request->isPost()) {
            if (!$this->_helper->formCheck('reset')) {
                $this->_redirect('/login/reset');
            } else {
                $email = $this->forms['reset']->getValue('email');
                $user = $this->_userMapper->findWhereEmailIs($email);
                $this->_userMapper->createPasswordReset($user);
                $this->_mailer->sendPasswordEmail($user);
                $this->_messenger->addMessage('resetpassword');
                $this->_redirect('/login/reset');
            }
        }
        $this->view->resetForm = $this->forms['reset'];
        $this->view->reset = isset($this->_messenger->resetpassword);
        $this->view->expired = isset($this->_messenger->expired);
    }

    /**
     * password action
     */
    public function passwordAction()
    {
        $user = $this->_getUserFromResetId();
        if ($this->_request->isPost()) {
            if (!$this->_helper->formCheck('password')) {
                $this->_redirect('/login/password');
            } else {
                $user->setPassword($this->forms['password']->getValue('password'));
                $user->getPasswordReset()->setUsed(true);
                $this->_userMapper->save($user);
                $this->_messenger->addMessage('newpassword');
                $this->_authenticate($user);
                $this->_redirect('/index');
            }
        }
        $this->forms['password']->addResetId($user->getResetHash());
        $this->view->username = $user->getUsername();
        $this->view->passwordForm = $this->forms['password'];
    }

    /**
     * Validate reset ID and get user
     * @return Application_Model_User 
     */
    protected function _getUserFromResetId()
    {
        if (!$this->_request->resetid) {
            $this->_redirect('/index');
        }
        $hash = $this->_request->resetid;
        $user = $this->_userMapper->findWhereResetIdIs($hash);

        if (!$user instanceof Application_Model_User) {
            $this->_redirect('/index');
        } elseif ($user->getPasswordReset()->hasExpired()) {
            $this->_messenger->addMessage('expired');
            $this->_redirect('/login/reset');
        }
        return $user;
    }

    /**
     * Authenticate user credentials
     * @param Application_Model_User $user
     * @return boolean
     */
    protected function _authenticate(Application_Model_User $user)
    {
        $authAdapter = $this->_userMapper->getAuthAdapter($user);
        $auth = Zend_Auth::getInstance();
        $result = $auth->authenticate($authAdapter);
        if ($result->isValid()) {
            $user = $authAdapter->getResultRowObject();
            $this->_session->user = (object) $user;
            return true;
        }
        return false;
    }
}